package com.yun.baselibrary.widget

import android.annotation.SuppressLint
import android.content.Context
import android.os.CountDownTimer
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatTextView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.OnLifecycleEvent
import java.util.concurrent.TimeUnit

/**
 * 倒计时控件
 */
class CountDownTextView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr), View.OnClickListener, LifecycleObserver {
    private var mCountDownTimer: CountDownTimer? = null
    private var mOnCountDownStartListener: OnCountDownStartListener? = null
    private var mOnCountDownTickListener: OnCountDownTickListener? = null
    private var mOnCountDownFinishListener: OnCountDownFinishListener? = null

    /**
     * 普通文本信息
     */
    private var mNormalText: String? = null
    private var mCountDownText: String? = null
    private var mOnClickListener: OnClickListener? = null

    //倒计时期间是否允许点击
    private var mClickable = false

    //是否把时间格式化成时分秒
    private var mShowFormatTime = false

    /**
     * 用来保存日，时，分，秒
     */
    var timeIndexes: Array<IntArray>?=null

    /**
     * 用来记录倒计时前面label的长度
     */
    var mBeforeIndex = 0
    private var mIsShowCompleteTv = false
    private val count = 0L
    private fun init(context: Context) {
        autoBindLifecycle(context)
    }

    /**
     * 控件自动绑定生命周期,宿主可以是activity或者fragment
     */
    private fun autoBindLifecycle(context: Context) {
        if (context is AppCompatActivity) {
            // 宿主是activity
            val fm = context.supportFragmentManager
            val fragments = fm.fragments
            if (fragments == null || fragments.size <= 0) {
                return
            }
            for (fragment in fragments) {
                val parent = fragment.view
                if (parent != null) {
                    val find = parent.findViewById<View>(id)
                    if (find === this) {
                        fragment.lifecycle.addObserver(this)
                        return
                    }
                }
            }
        }
        // 宿主是fragment
        if (context is LifecycleOwner) {
            (context as LifecycleOwner).lifecycle.addObserver(this)
        }
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    fun onResume() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    fun onDestroy() {
        Log.d("time", "onDestroy ")
        if (mCountDownTimer != null) {
            mCountDownTimer!!.cancel()
            mCountDownTimer = null
        }
        mOnCountDownStartListener = null
        mOnCountDownTickListener = null
        mOnCountDownFinishListener = null
    }

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        //        onDestroy();
    }

    /**
     * 非倒计时状态文本
     *
     * @param normalText 文本
     */
    fun setNormalText(normalText: String?): CountDownTextView {
        mNormalText = normalText
        text = normalText
        if (mCountDownTimer != null) {
            mCountDownTimer!!.cancel()
            mCountDownTimer = null
        }
        //        mOnCountDownStartListener = null;
//        mOnCountDownTickListener = null;
//        mOnCountDownFinishListener = null;
        return this
    }

    fun recycler() {
        if (mCountDownTimer != null) {
            mCountDownTimer!!.cancel()
            mCountDownTimer = null
        }
        mOnCountDownStartListener = null
        mOnCountDownTickListener = null
        mOnCountDownFinishListener = null
    }

    /**
     * 设置倒计时文本内容
     *
     * @param front  倒计时文本前部分
     * @param latter 倒计时文本后部分
     */
    fun setCountDownText(front: String, latter: String): CountDownTextView {
        mCountDownText = "$front%1\$s$latter"
        return this
    }

    /**
     * 顺序计时，非倒计时
     *
     * @param second 计时时间秒
     */
    fun startCount(second: Long) {
        startCount(second, TimeUnit.SECONDS)
    }

    fun startCount(time: Long, timeUnit: TimeUnit) {
        count(time, 0, timeUnit, false)
    }

    /**
     * 默认按秒倒计时
     *
     * @param second 多少秒
     */
    fun startCountDown(second: Long) {
        startCountDown(second, TimeUnit.SECONDS)
    }

    fun startCountDown(time: Long, timeUnit: TimeUnit) {
        count(time, 0, timeUnit, true)
    }

    /**
     * 是否格式化时间
     *
     * @param formatTime 是否格式化
     */
    fun setShowFormatTime(formatTime: Boolean): CountDownTextView {
        mShowFormatTime = formatTime
        return this
    }

    /**
     * 计时方案
     *
     * @param time        计时时长
     * @param timeUnit    时间单位
     * @param isCountDown 是否是倒计时，false正向计时
     */
    private fun count(time: Long, offset: Long, timeUnit: TimeUnit, isCountDown: Boolean) {
        if (time == 0L) {
            if (mOnCountDownTickListener != null) {
                mOnCountDownTickListener!!.onTick(1, "0时0分0秒", this@CountDownTextView)
            }
        }
        if (mCountDownTimer != null) {
            mCountDownTimer!!.cancel()
            mCountDownTimer = null
        }
        isEnabled = mClickable
        // 转换成毫秒
        val millisInFuture = timeUnit.toMillis(time) + 500
        // 时间间隔为1s
        val interval = TimeUnit.MILLISECONDS.convert(1, timeUnit)
        if (offset == 0L && mOnCountDownStartListener != null) {
            mOnCountDownStartListener!!.onStart()
        }
        if (TextUtils.isEmpty(mCountDownText)) {
            mCountDownText = text.toString()
        }
        mCountDownTimer = object : CountDownTimer(millisInFuture, interval) {
            override fun onTick(millisUntilFinished: Long) {
                val count =
                    if (isCountDown) millisUntilFinished else millisInFuture - millisUntilFinished + offset
                val l = timeUnit.convert(count, TimeUnit.MILLISECONDS)
                val showTime: String
                showTime = if (mShowFormatTime) {
                    generateTime(count, mIsShowCompleteTv)
                } else {
                    l.toString()
                }
                if (mOnCountDownTickListener != null) {
                    mOnCountDownTickListener!!.onTick(l, showTime, this@CountDownTextView)
                } else {
                    text = String.format(mCountDownText!!, showTime)
                }
            }

            override fun onFinish() {
                isEnabled = true
                mCountDownTimer = null
                if (!TextUtils.isEmpty(mNormalText)) {
                    text = mNormalText
                }
                if (mOnCountDownFinishListener != null) {
                    mOnCountDownFinishListener!!.onFinish()
                }
            }
        }
        mCountDownTimer?.start()
    }

    /**
     * 倒计时期间，点击事件是否响应
     *
     * @param clickable 是否响应
     */
    fun setCountDownClickable(clickable: Boolean): CountDownTextView {
        mClickable = clickable
        return this
    }

    fun setOnCountDownStartListener(onCountDownStartListener: OnCountDownStartListener?): CountDownTextView {
        mOnCountDownStartListener = onCountDownStartListener
        return this
    }

    fun setOnCountDownTickListener(onCountDownTickListener: OnCountDownTickListener?): CountDownTextView {
        mOnCountDownTickListener = onCountDownTickListener
        return this
    }

    fun setOnCountDownFinishListener(onCountDownFinishListener: OnCountDownFinishListener?): CountDownTextView {
        mOnCountDownFinishListener = onCountDownFinishListener
        return this
    }

    fun setBeforeIndex(beforeIndex: Int): CountDownTextView {
        mBeforeIndex = beforeIndex
        return this
    }

    /**
     * 设置是否显示精确到天的完整字段
     */
    fun setIsShowComplete(isShowComplete: Boolean): CountDownTextView {
        mIsShowCompleteTv = false
        return this
    }

    override fun onClick(v: View) {
        if (mCountDownTimer != null && !mClickable) {
            return
        }
        if (mOnClickListener != null) {
            mOnClickListener!!.onClick(v)
        }
    }

    override fun setOnClickListener(l: OnClickListener?) {
        mOnClickListener = l
        super.setOnClickListener(this)
    }

    interface OnCountDownStartListener {
        fun onStart()
    }

    interface OnCountDownTickListener {
        /**
         * 每秒自己刷新textView
         *
         * @param untilFinished 剩余的时间
         * @param showTime      可以直接使用的显示时间
         * @param tv            控件
         */
        fun onTick(untilFinished: Long, showTime: String?, tv: CountDownTextView?)
    }

    interface OnCountDownFinishListener {
        fun onFinish()
    }

    /**
     * 将毫秒转时分秒
     */
    @SuppressLint("DefaultLocale")
    fun generateTime(time: Long, isShowComplete: Boolean): String {
        val format: String
        timeIndexes = null
        val totalSeconds = time / 1000
        val seconds = (totalSeconds % 60).toInt()
        val minutes = (totalSeconds / 60 % 60).toInt()
        val hours = (totalSeconds / 3600 % 24).toInt()
        val days = (totalSeconds / (3600 * 24)).toInt()
        return if (!isShowComplete) {
            if (days > 0) {
//                format = String.format("%01d天%02d时%02d分%02d秒", days, hours, minutes, seconds);
                format = String.format("%01d天%02d时%02d分", days, hours, minutes)
                timeIndexes = Array(4) { IntArray(2) }
                timeIndexes!![0][0] = mBeforeIndex
                timeIndexes!![0][1] = String.format("%01d", days).length
                timeIndexes!![1][0] = mBeforeIndex + String.format("%01d", days).length + 1
                timeIndexes!![1][1] = String.format("%02d", hours).length
                timeIndexes!![2][0] = mBeforeIndex + String.format(
                    "%01d",
                    days
                ).length + String.format("%02d", hours).length + 2
                timeIndexes!![2][1] = String.format("%02d", minutes).length
                timeIndexes!![3][0] = mBeforeIndex + String.format(
                    "%01d",
                    days
                ).length + String.format("%02d", hours).length + String.format(
                    "%02d",
                    minutes
                ).length + 3
                timeIndexes!![3][1] = String.format("%02d", seconds).length
            } else if (hours > 0) {
                format = String.format("%02d时%02d分%02d秒", hours, minutes, seconds)
                timeIndexes = Array(3) { IntArray(2) }
                timeIndexes!![0][0] = mBeforeIndex
                timeIndexes!![0][1] = String.format("%02d", hours).length
                timeIndexes!![1][0] = mBeforeIndex + String.format("%02d", hours).length + 1
                timeIndexes!![1][1] = String.format("%02d", minutes).length
                timeIndexes!![2][0] = mBeforeIndex + String.format(
                    "%02d",
                    hours
                ).length + String.format("%02d", minutes).length + 2
                timeIndexes!![2][1] = String.format("%02d", seconds).length
            } else if (minutes > 0) {
//                format = String.format("%02d分%02d秒", minutes, seconds);
                format = String.format("%02d时%02d分%02d秒", hours, minutes, seconds)
                timeIndexes = Array(2) { IntArray(2) }
                timeIndexes!![0][0] = mBeforeIndex
                timeIndexes!![0][1] = String.format("%02d", minutes).length
                timeIndexes!![1][0] = mBeforeIndex + String.format("%02d", minutes).length + 1
                timeIndexes!![1][1] = String.format("%02d", seconds).length
            } else {
//                format = String.format("%2d秒", seconds);
                format = String.format("%02d时%02d分%02d秒", hours, minutes, seconds)
                timeIndexes = Array(1) { IntArray(2) }
                timeIndexes!![0][0] = mBeforeIndex
                timeIndexes!![0][1] = String.format("%02d", seconds).length
            }
            format
        } else {
            format = String.format("%01d 天 %01d 时 %01d 分 %01d 秒", days, hours, minutes, seconds)
            timeIndexes = Array(4) { IntArray(2) }
            timeIndexes!![0][0] = mBeforeIndex
            timeIndexes!![0][1] = String.format("%01d", days).length
            timeIndexes!![1][0] = mBeforeIndex + String.format("%01d", days).length + 3
            timeIndexes!![1][1] = String.format("%01d", hours).length
            timeIndexes!![2][0] =
                mBeforeIndex + String.format("%01d", days).length + String.format(
                    "%01d",
                    hours
                ).length + 6
            timeIndexes!![2][1] = String.format("%01d", minutes).length
            timeIndexes!![3][0] =
                mBeforeIndex + String.format("%01d", days).length + String.format(
                    "%01d",
                    hours
                ).length + String.format("%01d", minutes).length + 9
            timeIndexes!![3][1] = String.format("%01d", seconds).length
            format
        }
    }

    init {
        init(context)
    }
}